﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Pisces
{
    /**
     * 抽象的对象容器
     * created by wangqiang
    **/
    public abstract class AbstractEntityContainer : InterfaceEntityLiftcycle
    {
        /**
         * 存放对象的数组
         * key: 对象唯一id, value:实体对象
         */
        protected Dictionary<int, AbstractEntity> entityMap = new Dictionary<int, AbstractEntity>();

        /**
         * 缓存的对象数组，个数与map中相同，为了加速遍历而存在的
         */
        protected ArrayList entityArray = new ArrayList();

        /**
         * 添加一个对象
         */
        public T addEntity<T>() where T : AbstractEntity, new()
        {
            T entity = Activator.CreateInstance<T>();
            int instanceID = GUIDGenerator.generate();
            
            entityMap.Add(instanceID, entity);
            entityArray.Add(entity);
            
            entity.onInit();

            return entity;
        }

        /**
         * 移除一个对象
         */
        public void removeEntityByInstanceID(int instanceID)
        {
            AbstractEntity entity = null;
            for (int i = 0; i < entityArray.Count; i++)
            {
                Object entityElement = entityArray[i];
                if (typeof(AbstractEntity) != entityElement.GetType())
                {
                    continue;
                }

                if (((AbstractEntity)(entityElement)).InstanceID == instanceID)
                {
                    entity = (AbstractEntity) entityElement;
                    break;
                }
                
            }

            entityMap.Remove(instanceID);

            if (entity != null)
            {
                entity.onDestroy();
            }
        }

        /**
         * 根据实例id获取实例对象
         */
        public T getEntityByInstanceID<T>(int instanceID) where T : AbstractEntity
        {
            AbstractEntity value = entityMap.GetValueOrDefault(instanceID);
            if (value == null)
            {
                return null;
            }
            else
            {
                return value as T;
            }
        }

        public abstract void onInit();
        public abstract void onLoaded();
        public abstract void onAwake();
        public abstract void onUpdate(float deltaTime);
        public abstract void onDestroy();
    }
}